package lexer

//定义token的类型为字符串
type TokenType string

type Token struct {
	Type    TokenType //类型
	Literal string    //字符
	Line    int       //行号
	Column  int       //列号
}

const (
	ILLEGAL     = "ILLEGAL"     //未知的词法单元或字符
	EOF         = "EOF"         //文件结尾
	PACKAGE_EOF = "PACKAGE_EOF" //包文件结尾

	SEMICOLON             = ";"
	COMMA                 = ","
	SINGLE_QUOTATION_MARK = "'"  //单引号
	DOUBLE_QUOTATION_MARK = "\"" //双引号
	COLON                 = ":"
	DOT                   = "." //点号

	IDENT   = "IDENT"   //标识符(变量)
	INT     = "INT"     //整数
	FLOAT   = "FLOAT"   //浮点数
	STRING  = "STRING"  //字符串
	BOOLEAN = "BOOLEAN" //布尔值

	//================================ start 运算符 //================================//

	ASSIGN = "=" //赋值运算符

	//==== start 算数运算符 ====//
	PLUS       = "+"
	PLUSPLUS   = "++"
	MINUS      = "-"
	MINUSMINUS = "--"
	ASTERISK   = "*"
	SLASH      = "/"
	//==== start 算数运算符 ====//

	//==== start 比较运算符 ====//
	BANG     = "!"  //取反
	EQ       = "==" //等于
	NOT_EQ   = "!=" //不等于
	LT       = ">"  //大于
	GT       = "<"  //小于
	LARGE_GT = ">=" //大于等于
	SMALL_GT = "<=" //小于等于
	//==== start 比较运算符 ====//

	//================================ start 运算符 //================================//

	LPAREN   = "("
	RPAREN   = ")"
	LBRACKET = "["
	RBRACKET = "]"
	LBRACE   = "{"
	RBRACE   = "}"

	//关键字
	LET      = "LET"   //定义变量
	TRUE     = "TRUE"  //真
	FALSE    = "FALSE" //假
	IF       = "IF"
	ELSE     = "ELSE"
	FOR      = "FOR"
	BREAK    = "BREAK"
	RETURN   = "RETURN"
	FUNCTION = "FUNCTION" //函数
	IMPORT   = "IMPORT"   //导入文件
	CLASS    = "CLASS"    //类
)

//定义一个map用于存放关键字
var keywords = map[string]TokenType{
	"let":    LET,
	"true":   TRUE,
	"false":  FALSE,
	"if":     IF,
	"else":   ELSE,
	"for":    FOR,
	"break":  BREAK,
	"return": RETURN,
	"func":   FUNCTION,
	"class":  CLASS,
	"import": IMPORT,
}

//判断是不是关键字，不是返回标识符
func LookupIdent(ident string) TokenType {
	if tok, ok := keywords[ident]; ok {
		return tok
	}
	return IDENT
}
